home *** CD-ROM | disk | FTP | other *** search
/ Nothing but Tetris / Nothing but Tetris.iso / amiga / yactris / src / intuitet.c < prev    next >
C/C++ Source or Header  |  1994-01-01  |  21KB  |  840 lines

  1. /*
  2.     YacTris v0.0
  3.     Copyright ⌐1993 Jonathan P. Springer
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 1, or (at your option)
  8.     any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     For more details see the files README and COPYING, which should have
  20.     been included in this distribution.
  21.  
  22.     The author can be reached during the school year at these E-Mail addresses:
  23.  
  24.     springjp@screech.alfred.edu        (Internet)
  25.     springjp@ceramics.bitnet        (Bitnet)
  26.  
  27.     And can be reached by paper mail year-round at the following address:
  28.  
  29.     Jonathan Springer
  30.     360 W. Main St.
  31.     Dallastown, PA    17313-2014
  32.     USA
  33.  
  34. */
  35.  
  36.  
  37. /*
  38. **
  39. **  intuitet.c
  40. **
  41. **  If it has to to with Tetris and intuition display, it's probably here
  42. **
  43. */
  44.  
  45. /**************/
  46. /*  Includes  */
  47. /**************/
  48. #include <exec/types.h>
  49. #include <exec/memory.h>
  50. #include <dos/dos.h>
  51. #include <graphics/displayinfo.h>
  52. #include <intuition/intuition.h>
  53. #include <intuition/screens.h>
  54. #include <libraries/gadtools.h>
  55. #include <utility/tagitem.h>
  56. #include <clib/macros.h>
  57. #include <stdio.h>
  58. #include <stdlib.h>
  59. #include <time.h>
  60. #include <string.h>
  61. #include <math.h>
  62. #include <dbug.h>
  63. #include "yactris.h"
  64. #include <bruce.h>
  65.  
  66.  
  67. /****************/
  68. /*  Prototypes    */
  69. /****************/
  70.  
  71. #include <clib/exec_protos.h>
  72. #include <clib/intuition_protos.h>
  73. #include <clib/graphics_protos.h>
  74. #include <clib/gadtools_protos.h>
  75.  
  76. Prototype struct ScreenInfo *CreateScrInfo(struct Screen *);
  77. Prototype struct Window *OpenTWindow(struct ScreenInfo *, struct Menu *);
  78. Prototype void CloseTWindow(struct Window *);
  79. Prototype void FlagWindow(struct Window *, BOOL);
  80. Prototype void UpdateScores(struct Window *, struct ScreenInfo *, int, int, int);
  81. Prototype struct Screen *InquirePubScreen(struct ScreenInfo *);
  82. Prototype struct List *MakePubScrList(void);
  83. Prototype void FreePubScrList(struct List *);
  84. Prototype struct Window *OpenPWindow(struct ScreenInfo *, struct MsgPort *);
  85. Prototype void ClosePWindow(struct Window *);
  86. Prototype void DispPCount(struct ScreenInfo *, struct Window *, struct PieceRot *, int);
  87. Prototype void FreeScrInfo(struct ScreenInfo *);
  88.  
  89. const char ScrTitle[] = "YacTris v0.0";
  90.  
  91. /*
  92. **  Scoring IntuiTexts
  93. */
  94.     static UBYTE LevelT[4], ScoreT[16], LinesT[16];
  95.  
  96. #define NUMSCORETEXTS 6
  97.  
  98. static struct IntuiText ScoreTexts[NUMSCORETEXTS] = {
  99.     { 0,0,JAM1,0,0,NULL,"Level:",   &ScoreTexts[1] },
  100.     { 0,0,JAM1,0,0,NULL,LevelT,     &ScoreTexts[2] },
  101.     { 0,0,JAM1,0,0,NULL,"Score:",   &ScoreTexts[3] },
  102.     { 0,0,JAM1,0,0,NULL,ScoreT,     &ScoreTexts[4] },
  103.     { 0,0,JAM1,0,0,NULL,"Lines:",   &ScoreTexts[5] },
  104.     { 0,0,JAM1,0,0,NULL,LinesT,     NULL }
  105. };
  106.  
  107. static struct IntuiText NextText =
  108.     { 0,0,JAM1,0,0,NULL,"Next:",    NULL };
  109.  
  110. static UBYTE pText[8];
  111.  
  112. static struct IntuiText pIText =
  113.     { 0,0,JAM1,0,0,NULL,pText,        NULL };
  114.  
  115. /*
  116. **  Window IDCMP Flags
  117. */
  118. #define IDCMPFALSE  IDCMP_MENUPICK|IDCMP_CLOSEWINDOW
  119. #define IDCMPTRUE   IDCMPFALSE|IDCMP_INTUITICKS|IDCMP_VANILLAKEY
  120.  
  121. /*
  122. **
  123. **  CloseTWindow
  124. **
  125. */
  126. void CloseTWindow(struct Window *tw)
  127. {
  128.     ClearMenuStrip(tw);
  129.     CloseWindow(tw);
  130. }
  131.  
  132. /*
  133. **
  134. **  OpenTWindow()
  135. **
  136. **  Open a Tetris window on the passed screen.
  137. **
  138. */
  139. struct Window *OpenTWindow(struct ScreenInfo *si, struct Menu *tm)
  140. {
  141.     struct Window *w;
  142.  
  143.     DBUG_ENTER("OpenTWindow");
  144.  
  145.     /*    Open the window  */
  146.     if (w=OpenWindowTags(NULL, (Tag)
  147.     WA_Left,        100,
  148.     WA_Top,         20,
  149.     WA_Width,        si->WinWidth,
  150.     WA_Height,        si->WinHeight,
  151.     WA_IDCMP,        IDCMPFALSE,
  152.     WA_Title,        "YacTris",
  153.     WA_ScreenTitle,     ScrTitle,
  154.     WA_PubScreen,        si->s,
  155.     WA_DragBar,        TRUE,
  156.     WA_DepthGadget,     TRUE,
  157.     WA_CloseGadget,     TRUE,
  158.     WA_NoCareRefresh,   TRUE,
  159.     WA_Activate,        TRUE,
  160.     WA_SmartRefresh,    TRUE,
  161.     TAG_DONE)) {
  162.  
  163.     DBUG_PRINT("OTW",("Window Opened"));
  164.  
  165.     /*  Add the Menu strip    */
  166.     if (!SetMenuStrip(w, tm)) ByeBye(RETURN_WARN);
  167.  
  168.     DBUG_PRINT("OTW",("Menu Strip Added"));
  169.  
  170.     /*  Draw the BevelBox around the playing field.  */
  171.     DrawBevelBox(w->RPort, si->FieldInLeft-2, si->FieldInTop-1,
  172.         si->FieldInWidth+4, si->FieldInHeight+2,
  173.         GTBB_Recessed,  TRUE,
  174.         GT_VisualInfo,  si->vi,
  175.         TAG_END);
  176.  
  177.     /*  Draw the BevelBox around the next piece field.  */
  178.     DrawBevelBox(w->RPort, si->NextInLeft-2, si->NextInTop-1,
  179.         si->NextInWidth+4, si->NextInHeight+2,
  180.         GTBB_Recessed,  TRUE,
  181.         GT_VisualInfo,  si->vi,
  182.         TAG_END);
  183.  
  184.     /*  Add the "Next:" text  */
  185.     PrintIText(w->RPort, si->NextText, si->NextInLeft, si->NextInTop);
  186.  
  187.     }
  188.  
  189.     DBUG_RETURN(w);
  190. }
  191.  
  192. /*
  193. **
  194. **  CreateScrInfo()
  195. **
  196. **  Using the current tScreen as a pointer to a Screen structure, update all
  197. **  the fields in the ScreenInfo structure, which seems to be where I keep all
  198. **  sorts of fun information.
  199. **
  200. */
  201. struct ScreenInfo *CreateScrInfo(struct Screen *s)
  202. {
  203.     struct DrawInfo *drawInfo;
  204.     struct DisplayInfo dispInfo;
  205.     struct DimensionInfo dimInfo;
  206.     struct ScreenInfo *sInfo;
  207.  
  208.     ULONG modeID;
  209.  
  210.     UBYTE Text[16];
  211.  
  212.     int i,j;
  213.  
  214.     DBUG_ENTER("CreateScrInfo");
  215.  
  216.     if (!(sInfo = AllocMem(sizeof(struct ScreenInfo),MEMF_CLEAR)))
  217.     DBUG_RETURN(NULL);
  218.  
  219.     drawInfo = GetScreenDrawInfo(s);
  220.     modeID = GetVPModeID(&s->ViewPort);
  221.  
  222.     /*    Screen Address    */
  223.     sInfo->s = s;
  224.  
  225.     /*    Graphics Information  */
  226.     sInfo->planes = s->BitMap.Depth;
  227.  
  228.     if (!GetDisplayInfoData(NULL, (UBYTE *)&dimInfo,
  229.         sizeof (struct DimensionInfo), DTAG_DIMS, modeID))
  230.     ByeBye(RETURN_WARN);
  231.     sInfo->xTimes = 24;
  232.     if (dimInfo.Nominal.MaxX-dimInfo.Nominal.MinX < 1279) sInfo->xTimes = 12;
  233.     if (dimInfo.Nominal.MaxX-dimInfo.Nominal.MinX < 639 ) sInfo->xTimes = 6;
  234.  
  235.     if (!GetDisplayInfoData(NULL, (UBYTE *)&dispInfo,
  236.         sizeof (struct DisplayInfo), DTAG_DISP, modeID))
  237.     ByeBye(RETURN_WARN);
  238.     sInfo->yTimes = dispInfo.PropertyFlags & DIPF_IS_LACE ? 12 : 6;
  239.  
  240.     sInfo->pens[BACK] = drawInfo->dri_Pens[BACKGROUNDPEN];
  241.     sInfo->pens[SHINE] = drawInfo->dri_Pens[SHINEPEN];
  242.     sInfo->pens[SHADOW] = drawInfo->dri_Pens[SHADOWPEN];
  243.     sInfo->pens[FILL] = drawInfo->dri_Pens[FILLPEN];
  244.     sInfo->font = s->Font;
  245.  
  246.     /*    Window Dimensions  */
  247.     sInfo->WTop = s->WBorTop + s->Font->ta_YSize + 1;
  248.     sInfo->WBot = s->WBorBottom;
  249.     sInfo->WLeft = s->WBorLeft;
  250.     sInfo->WRight = s->WBorRight;
  251.  
  252.     /*    GadTools Stuff    */
  253.     sInfo->vi = GetVisualInfo(s, TAG_END);
  254.  
  255.     /*    Playing Field Location    */
  256.     sInfo->FieldInLeft = sInfo->WLeft + sInfo->xTimes;
  257.     sInfo->FieldInTop = sInfo->WTop + sInfo->yTimes;
  258.     sInfo->FieldInWidth = FWIDTH * sInfo->xTimes;
  259.     sInfo->FieldInHeight = FHEIGHT * sInfo->yTimes;
  260.  
  261.     /*    Next Piece Box Location and Text Info  */
  262.     sInfo->NextInLeft = sInfo->WLeft + (FWIDTH+2) * sInfo->xTimes;
  263.     sInfo->NextInTop = sInfo->WTop + sInfo->yTimes;
  264.  
  265.     sInfo->NextText = &NextText;
  266.     sInfo->NextText->FrontPen = sInfo->pens[SHADOW];
  267.     sInfo->NextText->BackPen = sInfo->pens[BACK];
  268.     sInfo->NextText->ITextFont = sInfo->font;
  269.  
  270.     sInfo->NextInWidth = MAX(i=IntuiTextLength(sInfo->NextText),4*sInfo->xTimes) +
  271.                 2*sInfo->xTimes;
  272.     sInfo->NextInHeight = sInfo->font->ta_YSize + 7*sInfo->yTimes;
  273.  
  274.     sInfo->NextText->LeftEdge = (sInfo->NextInWidth-i)/2;
  275.     sInfo->NextText->TopEdge = sInfo->yTimes;
  276.  
  277.     /*    Where to blit the next piece  */
  278.     sInfo->NPTop = sInfo->NextInTop+sInfo->font->ta_YSize + 2*sInfo->yTimes;
  279.     sInfo->NPLeft = sInfo->NextInLeft+(sInfo->NextInWidth-4*sInfo->xTimes)/2;
  280.  
  281.     /*    Scores display Information  */
  282.     sInfo->ScoreTexts = ScoreTexts;
  283.     for (i=0, sInfo->ScoreWidth=0; i<NUMSCORETEXTS; i += 2)
  284.     sInfo->ScoreWidth =
  285.         MAX(sInfo->ScoreWidth, IntuiTextLength(&sInfo->ScoreTexts[i]));
  286.     sprintf(ScoreT, "%d", 50000);
  287.     sInfo->ScoreWidth =
  288.     MAX(sInfo->ScoreWidth, IntuiTextLength(&sInfo->ScoreTexts[3]));
  289.  
  290.     sInfo->ScoreLeft = (sInfo->ScoreWidth<sInfo->NextInWidth) ?
  291.     sInfo->NextInLeft+(sInfo->NextInWidth-sInfo->ScoreWidth)/2 :
  292.     sInfo->NextInLeft;
  293.  
  294.     sInfo->ScoreTop = sInfo->NextInTop + 7*sInfo->xTimes + 3*sInfo->font->ta_YSize;
  295.     sInfo->ScoreHeight = 8*sInfo->font->ta_YSize;
  296.  
  297.     for (i=0; i<NUMSCORETEXTS; i++) {
  298.     sInfo->ScoreTexts[i].FrontPen = sInfo->pens[SHADOW];
  299.     sInfo->ScoreTexts[i].BackPen = sInfo->pens[BACK];
  300.     sInfo->ScoreTexts[i].ITextFont = sInfo->font;
  301.     if (!(i%2)) sInfo->ScoreTexts[i].LeftEdge =
  302.         (sInfo->ScoreWidth-IntuiTextLength(&sInfo->ScoreTexts[i]))/2;
  303.     sInfo->ScoreTexts[i].TopEdge = sInfo->font->ta_YSize * floor(i * 3/2);
  304.     }
  305.  
  306.     /*    Window dimensions  */
  307.     sInfo->WinWidth = sInfo->WLeft + sInfo->WRight + (FWIDTH+3)*sInfo->xTimes +
  308.     MAX(sInfo->NextInWidth, sInfo->ScoreWidth);
  309.     sInfo->WinHeight = sInfo->WTop + sInfo->WBot + 2*sInfo->yTimes +
  310.     MAX( FHEIGHT * sInfo->yTimes, sInfo->ScoreTop + sInfo->ScoreHeight);
  311.  
  312.     /*    pWindow Stuff  */
  313.  
  314.     i=MAX(sInfo->font->ta_YSize, 2*sInfo->yTimes);
  315.  
  316.     /*    pWindow IntuiText  */
  317.     sInfo->pIText = &pIText;
  318.     sInfo->pIText->FrontPen = sInfo->pens[SHADOW];
  319.     sInfo->pIText->BackPen = sInfo->pens[BACK];
  320.     sInfo->pIText->LeftEdge = 5*sInfo->xTimes;
  321.     sInfo->pIText->TopEdge = (i - sInfo->font->ta_YSize)/2;
  322.     sInfo->pIText->ITextFont = sInfo->font;
  323.  
  324.     sprintf(pText,"%d",222);
  325.  
  326.     sInfo->pxOffset = sInfo->WLeft + sInfo->xTimes;
  327.     sInfo->pyOffset = sInfo->WTop + sInfo->yTimes;
  328.  
  329.     sInfo->pxMult = 6*sInfo->xTimes + IntuiTextLength(sInfo->pIText);
  330.     sInfo->pyMult = i + sInfo->yTimes;
  331.     sInfo->pBMDown = (i - 2*sInfo->yTimes)/2;
  332.  
  333.     sInfo->pWidth = sInfo->pxOffset + 2*sInfo->pxMult + sInfo->WRight;
  334.     sInfo->pHeight = sInfo->pyOffset + 4*sInfo->pyMult + sInfo->WBot;
  335.  
  336.     FreeScreenDrawInfo(s, drawInfo);
  337.  
  338.     DBUG_RETURN(sInfo);
  339. }
  340.  
  341. /*
  342. **
  343. **  FlagWindow()
  344. **
  345. **  Modify the active/ghosted flags depending on whether Tetris is active or not.
  346. **
  347. */
  348. void FlagWindow(struct Window *tw, BOOL active)
  349. {
  350.     DBUG_ENTER("FlagWindow");
  351.  
  352.     if (active) {
  353.     OffMenu(tw, FULLMENUNUM(0, 0, NOSUB));
  354.     OnMenu(tw, FULLMENUNUM(0, 1, NOSUB));
  355.     ModifyIDCMP(tw, IDCMPTRUE);
  356.     } else {
  357.     OnMenu(tw, FULLMENUNUM(0, 0, NOSUB));
  358.     OffMenu(tw, FULLMENUNUM(0, 1, NOSUB));
  359.     ModifyIDCMP(tw, IDCMPFALSE);
  360.     }
  361.  
  362.     DBUG_VOID_RETURN;
  363. }
  364.  
  365. /*
  366. **
  367. **  UpdateScores
  368. **
  369. **  Print the current scores in the Scoring window
  370. **
  371. */
  372. void UpdateScores(struct Window *tw, struct ScreenInfo *si, int lev, int sc, int lin)
  373. {
  374.     int i;
  375.  
  376.     DBUG_ENTER("UpdateScores");
  377.  
  378.  
  379.     sprintf(LevelT, "%d", lev);
  380.     sprintf(ScoreT, "%d", sc);
  381.     sprintf(LinesT, "%d", lin);
  382.  
  383.     for (i=1; i<NUMSCORETEXTS; i+=2)
  384.     si->ScoreTexts[i].LeftEdge =
  385.         (si->ScoreWidth-IntuiTextLength(&si->ScoreTexts[i]))/2;
  386.  
  387.     DBUG_PRINT("US",("IntuiTexts initialized."));
  388.  
  389.     EraseRect(tw->RPort,si->ScoreLeft, si->ScoreTop,
  390.         si->ScoreLeft + si->ScoreWidth-1,
  391.         si->ScoreTop + si->ScoreHeight-1);
  392.  
  393.     DBUG_PRINT("US",("Rectangle cleared."));
  394.  
  395.     PrintIText(tw->RPort, si->ScoreTexts, si->ScoreLeft, si->ScoreTop);
  396.  
  397.     DBUG_PRINT("US",("Score Printed."));
  398.  
  399.     DBUG_VOID_RETURN;
  400. }
  401.  
  402. /*
  403. **
  404. **  InquirePubScreen
  405. **
  406. **  Returns the a pointer to a new, locked public screen to open the new window,
  407. **  or null if the Screen is the same as current or not selected.
  408. **
  409. */
  410. #define LV  (0)
  411. #define OK  (1)
  412. #define CAN (2)
  413.  
  414. struct Screen *InquirePubScreen(struct ScreenInfo *si)
  415. {
  416.     struct Screen *newScreen = NULL;
  417.  
  418.     struct List *myList;
  419.     struct Node *myNode;
  420.  
  421.     struct Window *lvw;
  422.     struct Gadget *glist=NULL, *pgad, *lv;
  423.     struct NewGadget newgad;
  424.  
  425.     int listcount = 0;
  426.  
  427.     BOOL done = FALSE;
  428.     int whichps = -1;
  429.     struct IntuiMessage *inMsg;
  430.     ULONG Class;
  431.     UWORD Code;
  432.     struct Gadget *Object;
  433.     ULONG oSeconds = 0, oMicros = 0;
  434.     ULONG Seconds = 0, Micros = 0;
  435.  
  436.     struct EasyStruct es = {
  437.     sizeof (struct EasyStruct), 0,
  438.     "YacTris",
  439.     "Unable to open Public Screen %s",
  440.     "Try Another"
  441.     };
  442.  
  443.     int i;
  444.  
  445.     DBUG_ENTER("InquirePubScreen");
  446.  
  447.     if (myList = MakePubScrList()) {
  448.  
  449.     for (myNode = myList->lh_Head; myNode->ln_Succ; myNode = myNode->ln_Succ) {
  450.     listcount++;
  451.     DBUG_PRINT("IPS",("Public Screen %s",myNode->ln_Name));
  452.     }
  453.  
  454.     newgad.ng_LeftEdge = si->WLeft+2*si->xTimes;
  455.     newgad.ng_TopEdge = si->WTop+2*si->font->ta_YSize;
  456.     newgad.ng_Width = 30*si->xTimes;
  457.     newgad.ng_Height = 10*si->font->ta_YSize;
  458.     newgad.ng_GadgetText = "_Public Screens";
  459.     newgad.ng_TextAttr = si->font;
  460.     newgad.ng_GadgetID = LV;
  461.     newgad.ng_Flags = 0;
  462.     newgad.ng_VisualInfo = si->vi;
  463.     newgad.ng_UserData = NULL;
  464.  
  465.     pgad = CreateContext(&glist);
  466.  
  467.     lv = pgad = CreateGadget(LISTVIEW_KIND, pgad, &newgad, (Tag)
  468.         GT_Underscore,        '_',
  469.         GTLV_Labels,        myList,
  470.         GTLV_ShowSelected,  NULL,
  471.         TAG_END);
  472.  
  473.     newgad.ng_TopEdge = si->WTop+13*si->font->ta_YSize;
  474.     newgad.ng_Width = 10*si->xTimes;
  475.     newgad.ng_Height = 2*si->font->ta_YSize;
  476.     newgad.ng_GadgetText = "_OK";
  477.     newgad.ng_GadgetID = OK;
  478.     newgad.ng_Flags = PLACETEXT_IN;
  479.  
  480.     pgad = CreateGadget(BUTTON_KIND, pgad, &newgad, GT_Underscore, '_', TAG_END);
  481.  
  482.     newgad.ng_LeftEdge = si->WLeft+22*si->xTimes;
  483.     newgad.ng_GadgetText = "_Cancel";
  484.     newgad.ng_GadgetID = CAN;
  485.  
  486.     pgad = CreateGadget(BUTTON_KIND, pgad, &newgad, GT_Underscore, '_', TAG_END);
  487.  
  488.     if (pgad) {
  489.  
  490.     if (lvw = OpenWindowTags(NULL, (Tag)
  491.         WA_Left,        120,
  492.         WA_Top,         30,
  493.         WA_Width,        si->WLeft+si->WRight+34*si->xTimes,
  494.         WA_Height,        si->WTop+si->WBot+16*si->font->ta_YSize,
  495.         WA_IDCMP,        BUTTONIDCMP|LISTVIEWIDCMP|
  496.                     IDCMP_CLOSEWINDOW|IDCMP_REFRESHWINDOW|
  497.                     IDCMP_VANILLAKEY,
  498.         WA_Gadgets,        glist,
  499.         WA_Title,        "Select a new screen",
  500.         WA_ScreenTitle,     "YacTris v0.0",
  501.         WA_PubScreen,        si->s,
  502.         WA_DragBar,        TRUE,
  503.         WA_DepthGadget,     TRUE,
  504.         WA_CloseGadget,     TRUE,
  505.         WA_ReportMouse,     TRUE,
  506.         WA_Activate,        TRUE,
  507.         WA_SimpleRefresh,   TRUE,
  508.         WA_AutoAdjust,        TRUE)) {
  509.  
  510.     GT_RefreshWindow(lvw, NULL);
  511.  
  512.     do {
  513.  
  514.     while (!done) {
  515.         Wait(1L << lvw->UserPort->mp_SigBit);
  516.         while (inMsg = GT_GetIMsg(lvw->UserPort)) {
  517.         Code = inMsg->Code;
  518.         Class = inMsg->Class;
  519.         Object = inMsg->IAddress;
  520.         oSeconds = Seconds;
  521.         oMicros = Micros;
  522.         Seconds = inMsg->Seconds;
  523.         Micros = inMsg->Micros;
  524.         GT_ReplyIMsg(inMsg);
  525.         switch(Class) {
  526.  
  527.         case IDCMP_CLOSEWINDOW:
  528.             whichps = -1;
  529.             done = TRUE;
  530.             break;
  531.  
  532.         case IDCMP_GADGETUP:
  533.             switch (Object->GadgetID) {
  534.  
  535.             case LV:
  536.             if (Code==whichps &&
  537.                 DoubleClick(oSeconds, oMicros, Seconds, Micros))
  538.             {
  539.                 done = TRUE;
  540.             } else {
  541.                 whichps = Code;
  542.                 DBUG_PRINT("IPS",("Currently Screen %d Selected",whichps));
  543.             }
  544.             break;
  545.  
  546.             case CAN:
  547.             whichps = -1;
  548.             case OK:
  549.             done = TRUE;
  550.             break;
  551.  
  552.             default:
  553.             break;
  554.             }
  555.             break;
  556.  
  557.         case IDCMP_REFRESHWINDOW:
  558.             GT_BeginRefresh(lvw);
  559.             GT_EndRefresh(lvw, TRUE);
  560.             break;
  561.  
  562.         case IDCMP_VANILLAKEY:
  563.             switch (Code) {
  564.  
  565.             case 'c': case 'C':
  566.             whichps = -1;
  567.  
  568.             case 'o': case 'O':
  569.             done = TRUE;
  570.             break;
  571.  
  572.             case 'p':
  573.             if (whichps == -1) whichps = 0;
  574.             else if (whichps < listcount-1) whichps++;
  575.             GT_SetGadgetAttrs(lv, lvw, NULL, GTLV_Selected, whichps);
  576.             break;
  577.  
  578.             case 'P':
  579.             if (whichps == -1) whichps = listcount - 1;
  580.             else if (whichps > 0) whichps--;
  581.             GT_SetGadgetAttrs(lv, lvw, NULL, GTLV_Selected, whichps);
  582.             break;
  583.  
  584.             }
  585.             break;
  586.  
  587.         default:
  588.             break;
  589.  
  590.         }
  591.         }
  592.     }
  593.  
  594.     DBUG_PRINT("IPS",("Screen %d selected",whichps));
  595.  
  596.     if (whichps != -1) {
  597.  
  598.         for (i=0, myNode = myList->lh_Head; i<whichps && myNode->ln_Succ;
  599.             i++, myNode = myNode->ln_Succ);
  600.  
  601.         if (!(newScreen=LockPubScreen(myNode->ln_Name))) {
  602.         struct List *l2;
  603.  
  604.         DBUG_PRINT("IPS",("Locking screen %s", myNode->ln_Name));
  605.         EasyRequest(lvw, &es, NULL, myNode->ln_Name);
  606.         l2 = MakePubScrList();
  607.         GT_SetGadgetAttrs(lv, lvw, NULL,
  608.             GTLV_Labels, l2, TAG_END, 0);
  609.         FreePubScrList(myList);
  610.         myList = l2;
  611.         for (myNode = myList->lh_Head, listcount=0; myNode->ln_Succ;
  612.             myNode = myNode->ln_Succ
  613.         ) {
  614.             listcount++;
  615.             DBUG_PRINT("IPS",("Public Screen %s",myNode->ln_Name));
  616.         }
  617.         done = FALSE;
  618.         }
  619.  
  620.     } else newScreen = NULL;
  621.  
  622.     } while (!done);
  623.  
  624.     if (newScreen==si->s) newScreen = NULL;
  625.  
  626.     CloseWindow(lvw);
  627.     }
  628.  
  629.     FreeGadgets(glist);
  630.     }
  631.  
  632.     FreePubScrList(myList);
  633.     }
  634.  
  635.     DBUG_PRINT("IPS",("Address Returned: %p", newScreen));
  636.  
  637.     DBUG_RETURN(newScreen);
  638.  
  639. }
  640.  
  641. /*
  642. **
  643. **  MakePubScrList()
  644. **
  645. **  Construct a list of Public screen names
  646. **
  647. */
  648. struct List *MakePubScrList(void)
  649. {
  650.     struct List *myList;
  651.     struct List *psList;
  652.     struct Node *psNode;
  653.     struct Node *myNode;
  654.  
  655.     BOOL fail = FALSE;
  656.  
  657.     DBUG_ENTER("MakePubScrList");
  658.  
  659.     if (!(myList = AllocMem(sizeof(struct List),MEMF_CLEAR)))
  660.     DBUG_RETURN(NULL);
  661.  
  662.     /*    Initialize the list  */
  663.     myList->lh_Head = (struct Node *) &myList->lh_Tail;
  664.     myList->lh_Tail = NULL;
  665.     myList->lh_TailPred = (struct Node *) &myList->lh_Head;
  666.  
  667.     psList = (struct List *) LockPubScreenList();
  668.  
  669.     for (psNode=psList->lh_Head; psNode->ln_Succ; psNode=psNode->ln_Succ) {
  670.  
  671.     DBUG_PRINT("MPSL",("Creating entry for %s",psNode->ln_Name));
  672.  
  673.     if (!(myNode = AllocMem(sizeof(struct Node),MEMF_CLEAR))) {
  674.         fail = TRUE;
  675.         break;
  676.     }
  677.     if (!(myNode->ln_Name = AllocMem(MAXPUBSCREENNAME,MEMF_CLEAR))) {
  678.         fail = TRUE;
  679.         FreeMem(myNode, sizeof(struct Node));
  680.         break;
  681.     }
  682.     strcpy(myNode->ln_Name, psNode->ln_Name);
  683.     AddTail(myList, myNode);
  684.  
  685.     }
  686.  
  687.     UnlockPubScreenList();
  688.  
  689.     if (fail) {
  690.     FreePubScrList(myList);
  691.     DBUG_RETURN(NULL);
  692.     }
  693.  
  694.     DBUG_RETURN(myList);
  695. }
  696.  
  697. /*
  698. **
  699. **  FreePubScrList()
  700. **
  701. **  Free the list of Public Screen names
  702. **
  703. */
  704. void FreePubScrList(struct List *l)
  705. {
  706.     struct Node *n;
  707.  
  708.     DBUG_ENTER("FreePubScrList");
  709.  
  710.     for ( n=RemTail(l); n; n=RemTail(l) ) {
  711.     DBUG_PRINT("FPSL",("Freeing entry for %s",n->ln_Name));
  712.     FreeMem(n->ln_Name,MAXPUBSCREENNAME);
  713.     FreeMem(n, sizeof(struct Node));
  714.     }
  715.  
  716.     DBUG_PRINT("FPSL",("Freeing List Structure"));
  717.     FreeMem(l, sizeof(struct List));
  718.  
  719.     DBUG_VOID_RETURN;
  720. }
  721.  
  722. /*
  723. **
  724. **  OpenPWindow()
  725. **
  726. **  Open the window that the piece count will be displayed in.
  727. **
  728. */
  729. struct Window *OpenPWindow(struct ScreenInfo *si, struct MsgPort *mp)
  730. {
  731.     struct Window *w;
  732.  
  733.     DBUG_ENTER("OpenPWindow");
  734.  
  735.     if (w=OpenWindowTags(NULL, (Tag)
  736.     WA_Left,        100 + si->WinWidth + 2*si->xTimes,
  737.     WA_Top,         20,
  738.     WA_Width,        si->pWidth,
  739.     WA_Height,        si->pHeight,
  740.     WA_Title,        "YacTris Piece Counts",
  741.     WA_ScreenTitle,     ScrTitle,
  742.     WA_PubScreen,        si->s,
  743.     WA_CloseGadget,     TRUE,
  744.     WA_DragBar,        TRUE,
  745.     WA_DepthGadget,     TRUE,
  746.     WA_NoCareRefresh,   TRUE,
  747.     WA_SmartRefresh,    TRUE,
  748.     TAG_DONE)) {
  749.  
  750.     w->UserPort = mp;
  751.  
  752.     ModifyIDCMP(w, IDCMP_CLOSEWINDOW);
  753.  
  754.     }
  755.  
  756.     DBUG_RETURN(w);
  757. }
  758.  
  759. /*
  760. **
  761. **  ClosePWindow()
  762. **
  763. **  Close the Pieces window safely
  764. **
  765. */
  766. void ClosePWindow(struct Window *pw)
  767. {
  768.     struct IntuiMessage *msg;
  769.     struct Node *succ;
  770.  
  771.     DBUG_ENTER("ClosePWindow");
  772.  
  773.     Forbid();
  774.  
  775.     msg = (struct IntuiMessage *) pw->UserPort->mp_MsgList.lh_Head;
  776.  
  777.     while (succ = msg->ExecMessage.mn_Node.ln_Succ) {
  778.     if (msg->IDCMPWindow == pw) {
  779.         Remove((struct Node *) msg);
  780.         ReplyMsg((struct Message *) msg);
  781.     }
  782.     msg = (struct IntuiMessage *) succ;
  783.     }
  784.  
  785.     pw->UserPort=NULL;
  786.     ModifyIDCMP(pw, 0L);
  787.  
  788.     Permit();
  789.  
  790.     CloseWindow(pw);
  791.  
  792.     DBUG_VOID_RETURN;
  793. }
  794.  
  795. /*
  796. **
  797. **  DispPCount()
  798. **
  799. **  Display the count for piece number P, including its BitMap
  800. **
  801. */
  802. void DispPCount(struct ScreenInfo *sInfo, struct Window *w,
  803.     struct PieceRot *p, int count)
  804. {
  805.     int x,y;
  806.  
  807.     DBUG_ENTER("DispPCount");
  808.  
  809.     x = sInfo->pxOffset + floor(p->type/4) * sInfo->pxMult;
  810.     y = sInfo->pyOffset + (p->type % 4) * sInfo->pyMult;
  811.  
  812.     EraseRect(w->RPort, x, y, x+sInfo->pxMult-1, y+sInfo->pyMult-1);
  813.  
  814.     BltBitMapRastPort(&p->BitMap, 0,0, w->RPort, x+sInfo->pBMDown,y,
  815.         4*sInfo->xTimes, 2*sInfo->yTimes, 0xc0);
  816.  
  817.     sprintf(pText, "%d", count);
  818.     PrintIText(w->RPort, sInfo->pIText, x, y);
  819.  
  820.     DBUG_VOID_RETURN;
  821. }
  822.  
  823. /*
  824. **
  825. **  FreeScrInfo()
  826. **
  827. **  The name says it all
  828. **
  829. */
  830. void FreeScrInfo(struct ScreenInfo *si)
  831. {
  832.     DBUG_ENTER("FreeScreenInfo");
  833.  
  834.     FreeVisualInfo(si->vi);
  835.  
  836.     FreeMem(si, sizeof(struct ScreenInfo));
  837.  
  838.     DBUG_VOID_RETURN;
  839. }
  840.